package com.baiqian.doupo.block;

import com.baiqian.doupo.Utils;
import com.baiqian.doupo.capability.DouPoModCapability;
import com.baiqian.doupo.capability.douqi.IDouQiCapability;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.PushReaction;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.IFormattableTextComponent;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.*;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType;
import net.minecraftforge.common.util.LazyOptional;

import javax.annotation.Nullable;
import java.util.List;

import static net.minecraft.util.EntityPredicates.IS_ALIVE;

class CeShiMoShiBei extends Block {
    public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
    private static final IntegerProperty TYPE = IntegerProperty.create("type", 1, 12);

    public CeShiMoShiBei() {
        super(Properties.create(Material.ROCK).setRequiresTool().hardnessAndResistance(5.0F, 6.0F).harvestTool(ToolType.PICKAXE).harvestLevel(1));
        this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.NORTH).with(TYPE, 11));
    }

    //方块是否可以在爆炸中掉落
    public boolean canDropFromExplosion(Explosion explosionIn) {
        return true;
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(TYPE, FACING);
        super.fillStateContainer(builder);
    }

    public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) {
        int type = stateIn.get(TYPE);
        Direction direction = stateIn.get(FACING);
        if (facingState.matchesBlock(this) && facingState.get(TYPE) != type) {
            return stateIn.with(FACING, facingState.get(FACING));
        }
        else {
            int col = type % 3;
            int row = (type - 1) / 3;//从上往下第几行[0,3]
            BlockPos posNow;
            switch (col) {//调整pos到中间
                case 0: {//最右边
                    switch (direction) {
                        case EAST:
                        case WEST:
                            posNow = new BlockPos(currentPos.getX(), currentPos.getY(), currentPos.getZ() - 1);
                            break;
                        case SOUTH:
                        default:
                        case NORTH:
                            posNow = new BlockPos(currentPos.getX() - 1, currentPos.getY(), currentPos.getZ());
                            break;
                    }
                    break;
                }
                case 1: {//最左边
                    switch (direction) {
                        case EAST:
                        case WEST:
                            posNow = new BlockPos(currentPos.getX(), currentPos.getY(), currentPos.getZ() + 1);
                            break;
                        case SOUTH:
                        default:
                        case NORTH:
                            posNow = new BlockPos(currentPos.getX() + 1, currentPos.getY(), currentPos.getZ());
                            break;
                    }
                    break;
                }
                default:
                case 2: {
                    posNow = new BlockPos(currentPos.getX(), currentPos.getY(), currentPos.getZ());
                    break;
                }
            }
            posNow = new BlockPos(posNow.getX(), posNow.getY() + row, posNow.getZ());//调整pos到顶部
            Block block = stateIn.getBlock();
            switch (direction) {
                case EAST:
                case WEST:
                default:
                    if (worldIn.getBlockState(posNow.south()).getBlock() == block &&
                            worldIn.getBlockState(posNow.north()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().south()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().north()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().south()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().north()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down().south()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down().north()).getBlock() == block &&
                            worldIn.getBlockState(posNow).getBlock() == block &&
                            worldIn.getBlockState(posNow.down()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down()).getBlock() == block
                    ) return stateIn;
                    break;
                case SOUTH:
                case NORTH:
                    if (worldIn.getBlockState(posNow.west()).getBlock() == block &&
                            worldIn.getBlockState(posNow.east()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().west()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().east()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().west()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().east()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down().west()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down().east()).getBlock() == block &&
                            worldIn.getBlockState(posNow).getBlock() == block &&
                            worldIn.getBlockState(posNow.down()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down()).getBlock() == block &&
                            worldIn.getBlockState(posNow.down().down().down()).getBlock() == block
                    ) return stateIn;
                    break;
            }
            //当方块被破坏后，其余方块将被替换成空气
            return Blocks.AIR.getDefaultState();
        }
    }
        /*
        *
        * DoubleBlockHalf doubleblockhalf = stateIn.get(HALF);
      if (facing.getAxis() == Direction.Axis.Y && doubleblockhalf == DoubleBlockHalf.LOWER == (facing == Direction.UP)) {
         return facingState.matchesBlock(this) && facingState.get(HALF) != doubleblockhalf ? stateIn.with(FACING, facingState.get(FACING)).with(OPEN, facingState.get(OPEN)).with(HINGE, facingState.get(HINGE)).with(POWERED, facingState.get(POWERED)) : Blocks.AIR.getDefaultState();
      } else {
         return doubleblockhalf == DoubleBlockHalf.LOWER && facing == Direction.DOWN && !stateIn.isValidPosition(worldIn, currentPos) ? Blocks.AIR.getDefaultState() : super.updatePostPlacement(stateIn, facing, facingState, worldIn, currentPos, facingPos);
      }
      * */


    //似乎创建方块
    @Nullable
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        BlockPos blockpos = context.getPos();
        World world = context.getWorld();
        if (blockpos.getY() < 253 &&
                world.getBlockState(blockpos.up()).isReplaceable(context) &&
                world.getBlockState(blockpos.up().up()).isReplaceable(context) &&
                world.getBlockState(blockpos.up().up().up()).isReplaceable(context)
        ) {
            Direction direction = context.getPlacementHorizontalFacing();
            switch (direction) {
                case EAST:
                case WEST:
                default:
                    if (world.getBlockState(blockpos.south()).isReplaceable(context) &&
                            world.getBlockState(blockpos.north()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().south()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().north()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().south()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().north()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().up().south()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().up().north()).isReplaceable(context)
                    ) return this.getDefaultState().with(FACING, context.getPlacementHorizontalFacing()).with(TYPE, 11);
                    break;
                case SOUTH:
                case NORTH:
                    if (world.getBlockState(blockpos.west()).isReplaceable(context) &&
                            world.getBlockState(blockpos.east()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().west()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().east()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().west()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().east()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().up().west()).isReplaceable(context) &&
                            world.getBlockState(blockpos.up().up().up().east()).isReplaceable(context)
                    ) return this.getDefaultState().with(FACING, context.getPlacementHorizontalFacing()).with(TYPE, 11);
                    break;
            }
        }
        return null;
    }

    //放下方块后就会执行这个
    public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
        worldIn.setBlockState(pos.up(), state.with(TYPE, 8), 3);
        worldIn.setBlockState(pos.up().up(), state.with(TYPE, 5), 3);
        worldIn.setBlockState(pos.up().up().up(), state.with(TYPE, 2), 3);
        Direction direction = state.get(FACING);
        switch (direction) {
            case EAST:
            case WEST:
            default:
                worldIn.setBlockState(pos.south(), state.with(TYPE, 12), 3);
                worldIn.setBlockState(pos.north(), state.with(TYPE, 10), 3);
                worldIn.setBlockState(pos.up().south(), state.with(TYPE, 9), 3);
                worldIn.setBlockState(pos.up().north(), state.with(TYPE, 7), 3);
                worldIn.setBlockState(pos.up().up().south(), state.with(TYPE, 6), 3);
                worldIn.setBlockState(pos.up().up().north(), state.with(TYPE, 4), 3);
                worldIn.setBlockState(pos.up().up().up().south(), state.with(TYPE, 3), 3);
                worldIn.setBlockState(pos.up().up().up().north(), state.with(TYPE, 1), 3);
                break;
            case SOUTH:
            case NORTH:
                worldIn.setBlockState(pos.east(), state.with(TYPE, 12), 3);
                worldIn.setBlockState(pos.west(), state.with(TYPE, 10), 3);
                worldIn.setBlockState(pos.up().east(), state.with(TYPE, 9), 3);
                worldIn.setBlockState(pos.up().west(), state.with(TYPE, 7), 3);
                worldIn.setBlockState(pos.up().up().east(), state.with(TYPE, 6), 3);
                worldIn.setBlockState(pos.up().up().west(), state.with(TYPE, 4), 3);
                worldIn.setBlockState(pos.up().up().up().east(), state.with(TYPE, 3), 3);
                worldIn.setBlockState(pos.up().up().up().west(), state.with(TYPE, 1), 3);
                break;
        }
    }

    //右键方块
    public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
        if (!worldIn.isRemote) {//右键发生的事情
//            worldIn.addParticle( ParticleTypes.ASH,-51,68,188,0.1,0.1,0.1);
            LazyOptional<IDouQiCapability> douQiCap = player.getCapability(DouPoModCapability.DOUQI_CAPABILTTY);
            if (douQiCap.isPresent()) {
                douQiCap.ifPresent((l) -> {
                    TranslationTextComponent content = new TranslationTextComponent("gui." + Utils.MOD_ID + ".color_" + l.getSoulPropertyMain());

//                    List<PlayerEntity> players = (List<PlayerEntity>) worldIn.getPlayers();
//                    for (int i = 0; i < players.size(); ++i) {
//                        PlayerEntity nearPlayer = players.get(i);
//                        if (Math.getDistance(pos.getX(), pos.getY(), pos.getZ(), nearPlayer.getPosX(), nearPlayer.getPosY(), nearPlayer.getPosZ()) < 21.0) {
//                            nearPlayer.sendMessage(ITextComponent.getTextComponentOrEmpty(content.getString() + l.getDouQiLevelStr() + " - " + player.getName().getString()), nearPlayer.getUniqueID());
//                        }
//                    }
                    PlayerEntity entity = player;
                    AxisAlignedBB range = new AxisAlignedBB(entity.getPosX()-21, entity.getPosY() - 21,  entity.getPosZ()-21,
                            entity.getPosX() +22, entity.getPosY() + 22,  entity.getPosZ()+22);//表示x，y，z所在的这一个格子
                    List<LivingEntity> livingEntities = entity.world.getEntitiesWithinAABB(LivingEntity.class,range,IS_ALIVE);
                    for (int i = 0; i < livingEntities.size(); ++i) {
                        LivingEntity livingEntity = livingEntities.get(i);
                        if(livingEntity instanceof PlayerEntity){
                            livingEntity.sendMessage(ITextComponent.getTextComponentOrEmpty(content.getString() + l.getDouQiLevelStr() + " - " + player.getName().getString()), livingEntity.getUniqueID());
                        }
                    }
                });
            }
        }
        return ActionResultType.func_233537_a_(worldIn.isRemote);
    }


    public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
        BlockPos blockpos = pos.down().down();
        BlockState blockstate = worldIn.getBlockState(blockpos);
        return state.get(TYPE) == 11 ? blockstate.isSolidSide(worldIn, blockpos, Direction.UP) : blockstate.matchesBlock(this);
    }

    /**
     * 能不能被推动
     * */
    public PushReaction getPushReaction(BlockState state) {
        return PushReaction.BLOCK;
    }

    @Override
    public BlockState rotate(BlockState state, Rotation rot) {
        return state.with(FACING, rot.rotate(state.get(FACING)));
    }

    @Override
    public BlockState mirror(BlockState state, Mirror mirrorIn) {
        return mirrorIn == Mirror.NONE ? state : state.rotate(mirrorIn.toRotation(state.get(FACING)));
    }

    @OnlyIn(Dist.CLIENT)
    public long getPositionRandom(BlockState state, BlockPos pos) {
        return MathHelper.getCoordinateRandom(pos.getX(), pos.down(state.get(TYPE) == 11 ? 0 : 1).down(state.get(TYPE) == 11 ? 0 : 1).getY(), pos.getZ());
    }

    @Override
    @OnlyIn(Dist.CLIENT)
    public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
        tooltip.add(this.getDescription().mergeStyle(TextFormatting.GRAY));
    }

    @OnlyIn(Dist.CLIENT)
    public IFormattableTextComponent getDescription() {
        return new TranslationTextComponent(this.getTranslationKey() + ".1");
    }
}
